<?php
namespace control;
/*
*应收账龄分析类
*/

class incomeAgeAnalysisClass extends adIndexClass
{
    private const page = 'incomeAgeAnalysis';
    private const title = '应收账龄分析';

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "客户编码" => text(array("name" => "code")),
                    "客户名称"   => text(array("name" => "name")),
                    "分析日期"   => text(array("name" => "createTime", 'value' => $this->date, 'laydate' => ['type' => 'date'])),
                ]
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /*列表-查询条件*/
    public function home()
    {
        $html = $this->homeOptions(false);
        //控件
        $button = "";
        if ($this->power(self::page, "export")) {
            $button .="<span class='spanButton' onclick=\"layer('importTemplate','exportFrame',{cla:'".self::page."'})\">导出</span>";
        }
        //返回
        return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button));
    }

    /*客户列表-查询结果*/
    public function homeSearch($cla = self::page)
    {
        $date = $this->post('createTime')?:$this->date;
        //like查询数组
        $like = array(
            'b.orderNo' => $this->post('code'),
            'b.companyName' => $this->post('name'),
        );
        //全等查询数组
        $equal = array(
            'a.coid' => self::$coid,
            'a.type' => '客户',
        );
        $recWhere=$and="";
        if ($date){
            $recWhere.=" and targetDate <= '$date'";
            $and.=" and a.targetDate <='$date'";
        }
        //获取查询结果
        $where = search(array("like" => $like, "=" => $equal)) .$and;
        $page = $this->page(array("table" => "record as a join kehu as b on a.typeId = b.khid", 'field' => "any_value(b.companyName) as companyName,any_value(b.orderNo) as code,any_value(a.id) as id,any_value(b.khid) as khid", "where" => $where . " group by a.typeId", "order" => ""));
        $_SESSION[self::page]['sql'] = $page['fullSql'];
        $_SESSION[self::page]['date'] = $date;
        //获取表头
        $tr = [];
        //获取记录
        foreach ($page['array'] as $array) {
            //实际收款金额
            $recMoney = find(array('table'=>'record','where'=>"typeId = '$array[khid]' and direction = '-'".$recWhere,'sum'=>"money"));
            $recMoney = $recMoney!=0?-$recMoney:0;
            //应收款项
            $khMoney = find(array('table'=>'record','where'=>"typeId = '$array[khid]' and direction = '+'".$recWhere,'sum'=>"money"));
            //应收余额
            $remindMoney =  round($khMoney-$recMoney,2);
            //计算逾期金额
            $overdueMoney = $this->saleOverdue($date,$array['khid']);
            //逾期比率
            $overdueRate = $this->calcuRate($remindMoney,$overdueMoney);
            $tr[] = array($array['code'], $array['companyName'], $khMoney, $recMoney,$remindMoney, $overdueMoney, $overdueRate.'%',
                $this->saleOverdue($date,$array['khid'],0,30),
                $this->calcuRate($remindMoney,$this->saleOverdue($date,$array['khid'],0,30)).'%',
                $this->saleOverdue($date,$array['khid'],30,60),
                $this->calcuRate($remindMoney,$this->saleOverdue($date,$array['khid'],30,60)).'%',
                $this->saleOverdue($date,$array['khid'],60,90),
                $this->calcuRate($remindMoney,$this->saleOverdue($date,$array['khid'],60,90)).'%',
                $this->saleOverdue($date,$array['khid'],90),
                $this->calcuRate($remindMoney,$this->saleOverdue($date,$array['khid'],90)).'%'
            );
        }
        $list = $this->tableMany(array("tr" => $tr, 'thead' => false));
        $html = <<<eof
<div class='table_many_shell'>
<div style="height: 30px;line-height: 30px;padding: 0 5px;">分析日期：{$date}</div>
 <table class="tableMany">
                    <thead>
                        <tr>
                            <td rowspan="2" class="center" style="vertical-align:middle">客户编码</td>
                            <td rowspan="2" class="center" style="vertical-align:middle">客户名称</td>
                            <td rowspan="2" class="center" style="vertical-align:middle">应收金额</td>
                            <td rowspan="2" class="center" style="vertical-align:middle">收款金额</td>
                            <td rowspan="2" class="center" style="vertical-align:middle">应收余额</td>
                            <td rowspan="2" class="center" style="vertical-align:middle">逾期金额</td>
                            <td rowspan="2" class="center" style="vertical-align:middle">逾期比率</td>
                            <td colspan="2" class="center">1-30天</td>
                            <td colspan="2" class="center">31-60天</td>
                            <td colspan="2" class="center">61-90天</td>
                            <td colspan="2" class="center">90天以上</td>
                        </tr>
                        <tr><td>金额</td><td>比率</td><td>金额</td><td>比率</td><td>金额</td><td>比率</td><td>金额</td><td>比率</td></tr>
                    </thead>
                    <tbody>
                       $list
                    </tbody>
                </table>
</div>
eof;

        //控件
        $button = "";
        //返回
        $json['html'] = $page['hint'] . $button . "<form name='listForm'>" . $html . "</form>" . $page['button'] . clear;
        return json_encode($json, 320);
    }

    /**
     * 计算比率
     * @param $saleMoney
     * @param $overdueMoney
     * @return float|int
     */
    private function calcuRate($saleMoney,$overdueMoney): float|int
    {
        return $saleMoney>0?round(($overdueMoney/$saleMoney)*100,2):0;
    }

    /**
     * 逾期金额
     * @param $date
     * @param $khid
     * @param int $min
     * @param int $max
     * @return float
     */
    private function saleOverdue($date,$khid,$min=0,$max=0): float
    {

        if ($min >0 || $max >0){
            $where = '';
            if ($min >0){
                $where.=" and DATEDIFF('$date',recordDate) > $min";
            }
            if ($max >0){
                $where.=" and DATEDIFF('$date',recordDate) > 0 and DATEDIFF('$date',recordDate) <= $max";
            }
        }else{
            $where = "and DATEDIFF('$date',recordDate) > settlementDay";
        }
        $saleSendOrderAll = find(array('table'=>'sale_send_order','where'=>"khid = '$khid' and coid = '".self::$coid."' and settlementType = '月结' $where and state = '已确认' order by recordDate asc"));
        $money = 0;//逾期金额
        foreach ($saleSendOrderAll['array'] as $saleSendOrder){
            //应收金额
            $saleMoney = find(array('table'=>'record','where'=>"typeId = '$khid' and orderNo = '$saleSendOrder[orderNo]'",'sum'=>"money"));

            //已核销金额
            //收款单核销
            $checkMoney = find(array('table'=>'receipt as a join receipt_source as b on a.id = b.orderId','single'=>"a.state = '已确认' and a.coid = '".self::$coid."' and b.sourceId = '$saleSendOrder[id]'",'field'=>"ifnull(sum(b.money),0) as money"))['money'];
            //核销单核销
            $checkMoney+=find(array('table'=>"write_off_order as a join write_off_order_detail as b on a.id = b.orderId",'single'=>"a.state = '已确认' and a.coid = '".self::$coid."' and b.sourceId = '$saleSendOrder[id]'","field"=>"ifnull(sum(b.money),0) as money"))['money'];
            //转单
            $checkMoney+=find(array('table'=>"write_off_order as a join write_off_order_replace as b on a.id = b.orderId",'single'=>"a.state = '已确认' and a.coid = '".self::$coid."' and b.sourceId = '$saleSendOrder[id]'","field"=>"ifnull(sum(b.money),0) as money"))['money'];
            if (round($checkMoney) < round($saleMoney)){
                $money += $saleMoney-$checkMoney;
            }
        }
        return round($money,2);
    }

    /**
     * 导出
     */
    public function exportData()
    {
        $templateId = $this->get('templateId');
        if (!$this->power(self::page, 'export')) {
            $_SESSION['warn'] = "您还没有导出的权限";
        }  else {
            $date = $_SESSION[self::page]['date'];
            $recWhere="";
            if ($date){
                $recWhere.=" and targetDate <= '$date'";
            }
            $data = [];
            /***********标题**********/
            $title =[];
            $tempFieldAll = importTemplateClass::templateField(self::page, 'exportFieldInit', id:$templateId);
            foreach ($tempFieldAll as $array) {
                if ($array['display']){
                    $title[] = $array['aliasName'];
                }
            }
            $sql   = $_SESSION[self::page]['sql'];
            $result   = sqlFind($sql);
            //导出数据生成
            foreach ($result as $array){
                $column = [];
                //实际收款金额
                $recMoney = find(array('table'=>'record','where'=>"typeId = '$array[khid]' and direction = '-'".$recWhere,'sum'=>"money"));
                $recMoney = $recMoney!=0?-$recMoney:0;
                //应收款项
                $khMoney = find(array('table'=>'record','where'=>"typeId = '$array[khid]' and direction = '+'".$recWhere,'sum'=>"money"));
                //应收余额
                $remindMoney =  round($khMoney-$recMoney,2);
                //计算逾期金额
                $overdueMoney = $this->saleOverdue($date,$array['khid']);
                //逾期比率
                $overdueRate = $this->calcuRate($remindMoney,$overdueMoney);
                foreach ($tempFieldAll as $templateField){
                    if ($templateField['display']){
                        $column[] = match ($templateField['columnName']){
                            '客户编码'=>$array['code'],
                            '客户名称'=>$array['companyName'],
                            '应收金额'=>$khMoney,
                            '收款金额'=>$recMoney,
                            '应收余额'=>$remindMoney,
                            '逾期金额'=>$overdueMoney,
                            '逾期比率'=>$overdueRate.'%',
                            '金额(1-30天)'=> $this->saleOverdue($date,$array['khid'],0,30),
                            '比率(1-30天)'=>    $this->calcuRate($remindMoney,$this->saleOverdue($date,$array['khid'],0,30)).'%',
                            '金额(31-60天)'=>    $this->saleOverdue($date,$array['khid'],30,60),
                            '比率(31-60天)'=> $this->calcuRate($remindMoney,$this->saleOverdue($date,$array['khid'],30,60)).'%',
                            '金额(61-90天)'=> $this->saleOverdue($date,$array['khid'],60,90),
                            '比率(61-90天)'=> $this->calcuRate($remindMoney,$this->saleOverdue($date,$array['khid'],60,90)).'%',
                            '金额(90天以上)'=>   $this->saleOverdue($date,$array['khid'],90),
                            '比率(90天以上)'=>  $this->calcuRate($remindMoney,$this->saleOverdue($date,$array['khid'],90)).'%',
                            default=>'',
                        };
                    }
                }
                $data[] = $column;
            }

            $text = $this->control['name'] . "导出了应收账龄分析";
            $this->logText(["type" => self::page, "text" => $text]);
            $this->excelOut($title, $data, "应收账龄分析.xlsx");
            exit(0);
        }
        header("Location:" . getenv("HTTP_REFERER"));
    }

    /**
     * 导出模板字段初始化
     * @return array[]
     */
    public function exportFieldInit($classify=''): array
    {
        return match ($classify) {
            default=>  [
                [
                    'columnName'=>'客户编码',
                    'aliasName'=>'客户编码',
                ],
                [
                    'columnName'=>'客户名称',
                    'aliasName'=>'客户名称',
                ],
                [
                    'columnName'=>'应收金额',
                    'aliasName'=>'应收金额',
                ],
                [
                    'columnName'=>'收款金额',
                    'aliasName'=>'收款金额',
                ],
                [
                    'columnName'=>'应收余额',
                    'aliasName'=>'应收余额',
                ],
                [
                    'columnName'=>'逾期金额',
                    'aliasName'=>'逾期金额',
                ],
                [
                    'columnName'=>'逾期比率',
                    'aliasName'=>'逾期比率',
                ],
                [
                    'columnName'=>'金额(1-30天)',
                    'aliasName'=>'金额(1-30天)',
                ],
                [
                    'columnName'=>'比率(1-30天)',
                    'aliasName'=>'比率(1-30天)',
                ],
                [
                    'columnName'=>'金额(31-60天)',
                    'aliasName'=>'金额(31-60天)',
                ],
                [
                    'columnName'=>'比率(31-60天)',
                    'aliasName'=>'比率(31-60天)',
                ],
                [
                    'columnName'=>'金额(61-90天)',
                    'aliasName'=>'金额(61-90天)',
                ],
                [
                    'columnName'=>'比率(61-90天)',
                    'aliasName'=>'比率(61-90天)',
                ],
                [
                    'columnName'=>'金额(90天以上)',
                    'aliasName'=>'金额(90天以上)',
                ],
                [
                    'columnName'=>'比率(90天以上)',
                    'aliasName'=>'比率(90天以上)',
                ],
            ]
        };
    }
}

